import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';

import { Device,Tag,TAG_PREFIX, DevicesUtils,DeviceNetProperty,DeviceType } from '../../../_models/device';
import { Utils } from '../../../_helpers/utils';
import { DeviceTagDialog } from '../../../device/device.component';
import { BitmaskComponent } from '../../../gui-helpers/bitmask/bitmask.component';
import { ProjectService } from '../../../_services/project.service';
import { TagPropertyComponent } from '../../../device/tag-property/tag-property.component';
import { Node, NodeType } from '../../../gui-helpers/treetable/treetable.component';
import { HmiService } from '../../../_services/hmi.service';
import { HttpClient } from '@angular/common/http';
import { MeasurePropertyComponent } from '../../../editor/measure-property/measure-property.component';

interface Variable {
    id: string;
    name: string;
    initValue: string;
}

@Component({
    selector: 'flex-variable',
    templateUrl: './flex-variable.component.html',
    styleUrls: ['./flex-variable.component.css']
})
export class FlexVariableComponent implements OnInit {
    @Input() data: any;
    @Input() variableId: string;
    @Input() value: any;
    @Input() allowManualEdit = false;
    @Input() variableValue: string;
    @Input() variableLabel = 'gauges.property-variable-value';
    @Input() withStaticValue = true;
    @Input() withBitmask = false;
    @Input() tagLabel = 'gauges.property-tag-label';
    @Input() tagTitle = '';
    @Input() bitmask: number;

    @Output() onchange: EventEmitter<any> = new EventEmitter();
    @Output() valueChange: EventEmitter<any> = new EventEmitter();

    public manualEdit = false;

    variableList: any = [];
    currentVariable: Variable = null;

    deviceMeasureList: any[]=[];
    form: any={};
    deviceSelected: Device = null;
    devices: any;
    deviceList: Device[];
    dirty = false;

    tagsMap = {};

    url='';
    addUrl=true;
    jsonParam: string;
    measureCode: string;
    deviceId: string;
    polling: number;

    constructor(
        private projectService: ProjectService,
        private hmiService: HmiService,
        private http: HttpClient,
        public dialog: MatDialog) {
    }

    ngOnInit() {
        console.log(this.value,this.variableId,this.variableValue,this.data);
        if (!this.value) {
            this.value = {
                variableId: this.variableId
            };
        } else if (this.value.variableId) {
            this.variableId = this.value.variableId;
        }
        this.deviceList = this.data.devices;
        if(this.variableId){
            const device=this.projectService.getDeviceFromTagId(this.variableId);
            if(device && device.property){
                this.polling=device.polling;
                if(device.property.jsonParam){
                    this.deviceId=device.property.jsonParam.deviceId;
                    this.getMeasureList(this.deviceId);
                    this.measureCode=device.property.jsonParam.keyword;
                }
            }
        }

    }

    getMeasureList(deviceId){
        console.log(deviceId);
        if(deviceId){
            this.http.post('/deviceApi/device/mgt/processedDeviceMeasureListPage',{current:1,size:100,deviceId}).subscribe((res: any) => {
                if(res.code===200){
                    this.deviceMeasureList=res.data.list;
                }
            });
        }else{
            this.deviceMeasureList=[];
        }
    }

    getDeviceName() {
        let device = DevicesUtils.getDeviceFromTagId(this.data.devices, this.variableId);
        if (device) {
            return device.name;
        }
        return '';
    }

    getVariableName() {
        let tag = DevicesUtils.getTagFromTagId(this.data.devices, this.variableId);
        if (tag) {
            let result = tag.label || tag.name;
            if (result && tag.address && result !== tag.address) {
                return result + ' - ' + tag.address;
            }
            if (tag.address) {
                return tag.address;
            }
            return result;
        }
        return '';
    }

    getVariableMask(): string {
        if (this.bitmask) {
            return `bit ${Utils.findBitPosition(this.bitmask).toString()}`;// this.bitmask.toString(16);
        }
        return '';
    }

    onChanged() {
        let tag = DevicesUtils.getTagFromTagId(this.data.devices, this.variableId);
        console.log(tag,this.projectService.getDevices(),this.data.devices, this.variableId);
        if (tag) {
            this.value.variableId = tag.id;
            this.value.variableRaw = tag;
        } else {
            this.value.variableId = null;
            this.value.variableRaw = null;
        }
        if (this.withBitmask) {
            this.value.bitmask = this.bitmask;
        }
        this.value.variableValue = this.variableValue;
        this.onchange.emit(this.value);   // Legacy
        this.valueChange.emit(this.value);
    }

    onBindMeasure(){
        let dialogRef = this.dialog.open(MeasurePropertyComponent, {
            position: { top: '60px' },
            data: {
                variableId:this.variableId,
                value:this.value,
                data:this.data
             }
        });

        dialogRef.afterClosed().subscribe((result) => {
            if (result) {
                const variableDefaultProp = result.variableDefaultProp;
                this.value.variableDefaultProp=variableDefaultProp;
                console.log(result,this.data.devices);
                this.variableId=result.variableId;
                this.data.devices=Object.values(this.projectService.getDevices());
                console.log(result,this.data.devices);
                this.onChanged();
            }
        });

    }

    onBindTag() {
        console.log('是我',this.data.devices,this.variableId);
        let currentDevice={};
        if(this.url){
            currentDevice=this.deviceSelected;
        }else{
            currentDevice=DevicesUtils.getDeviceFromTagId(this.data.devices, this.variableId);
        }
        console.log(currentDevice);
        let dialogRef = this.dialog.open(DeviceTagDialog, {
            position: { top: '60px' },
            data: { variableId: this.variableId, devices: this.data.devices }
        });

        dialogRef.afterClosed().subscribe((result) => {
            console.log(result);
            if (result) {
                this.variableId = result.variableId;
                this.onChanged();
            }
        });
    }

    setVariable(tag: Tag) {
        console.log('设置tag变量id',tag);
        if (tag) {
            this.variableId = tag.id;
        } else {
            this.variableId = null;
        }
        this.onChanged();
    }

    onSetBitmask() {
        let dialogRef = this.dialog.open(BitmaskComponent, {
            position: { top: '60px' },
            data: { bitmask: this.bitmask }
        });

        dialogRef.afterClosed().subscribe((result) => {
            if (result) {
                this.bitmask = result.bitmask;
                this.onChanged();
            }
        });
    }

    onAddDevice(){
        this.url='';
        this.addUrl=!this.addUrl;
    }

    onMeasure(){
        console.log(this.deviceId,this.measureCode,this.polling);
        // 添加设备时，应该用设备id作为主键
        let device = new Device(this.deviceId+':'+this.measureCode);
        // 此处没有设备名称
        device.name=this.deviceId+':'+this.measureCode;
        device.property = new DeviceNetProperty();
        device.property.address='https://iot-device-service-1.dev.ennew.com/device/measureDefinitionListPage';
        device.property.jsonParam={
            keyword:this.measureCode,
            current:1,
            size:10,
            deviceId:this.deviceId,
            dataQueryFlag:true
        };
        device.property.method='POST';
        device.polling=(this.polling || 3)*1000;
        device.enabled = false;
        device.tags = {};
        this.editDevice(device);
    }



    onMeasureCodeChange(measureCode){
        this.measureCode=measureCode;
    }

    onShowTag(){
        let deviceId=this.url.lastIndexOf('/')>-1?this.url.substring(this.url.lastIndexOf('/')+1):'';
        let index = this.deviceList.findIndex(d=>d.id===deviceId);
        if(index>-1){
            const device=this.deviceList[index];
            this.editDevice(device);
        }else{
            if(!deviceId){
                deviceId=JSON.parse(this.jsonParam).deviceId;
            }
            this.addDevice(deviceId);
        }
        // // 这里调用接口，订阅
        // if(this.addUrl){
        //     this.addDevice();
        // }else{
        //     console.log(this.bindDeviceId,this.devices);
        //     const device=this.devices[this.bindDeviceId];
        //     this.editDevice(device);
        // }

    }

    onUrlChange(url){
        this.url=url;
        let deviceId=url.lastIndexOf('/')>-1?url.substring(url.lastIndexOf('/')+1):'';
        this.deviceSelected=this.projectService.getDeviceFromId(deviceId);
        this.tagsMap=this.deviceSelected.tags;
    }

    addDevice(newId){
        // 添加设备时，应该用设备id作为主键
        let device = new Device(newId);
        // 此处没有设备名称
        device.name=newId;
        device.property = new DeviceNetProperty();
        device.property.address=this.url;
        device.property.jsonParam=this.jsonParam;
        device.polling=(this.polling || 3)*1000;
        device.enabled = false;
        device.tags = {};
        this.editDevice(device);

    }

    editDevice(device){
        let olddevice = JSON.parse(JSON.stringify(device));
        let tempdevice = JSON.parse(JSON.stringify(device));
        device.type = 'WebAPI';
        device.enabled = true;
        // if (this.appService.isClientApp || this.appService.isDemoApp) {
        //     delete device.property;
        // }
        if (device.property && tempdevice.property) {
            device.property.address = tempdevice.property.address;
            device.property.port = parseInt(tempdevice.property.port);
            device.property.slot = parseInt(tempdevice.property.slot);
            device.property.rack = parseInt(tempdevice.property.rack);
            device.property.slaveid = tempdevice.property.slaveid;
            device.property.baudrate = tempdevice.property.baudrate;
            device.property.databits = tempdevice.property.databits;
            device.property.stopbits = tempdevice.property.stopbits;
            device.property.parity = tempdevice.property.parity;
            device.property.options = tempdevice.property.options;
            device.property.method = tempdevice.property.method || 'GET';
            device.property.format = tempdevice.property.format;
            device.property.broadcastAddress = tempdevice.property.broadcastAddress;
            device.property.adpuTimeout = tempdevice.property.adpuTimeout;
            if (tempdevice.property.connectionOption) {
                device.property.connectionOption = tempdevice.property.connectionOption;
            }
        }
        this.projectService.setDevice(device, olddevice, null);
        this.devices = this.projectService.getDevices();
        this.deviceSelected=device;
        this.addOpcTags(null);
        // this.showMode = DeviceViewModeType.tags;
        // this.deviceList.updateDeviceValue();
        // this.deviceList.setSelectedDevice(device);
    }

    addOpcTags(tag: Tag) {
        console.log('点击我',this.deviceSelected, tag, this.devices );
        let dialogRef = this.dialog.open(TagPropertyComponent, {
            panelClass: 'dialog-property',
            data: { device: this.deviceSelected, tag: tag, devices: this.devices },
            position: { top: '60px' }
        });
        dialogRef.afterClosed().subscribe(result => {
            console.log(result);
            if (result) {
                let tagId='';
                if(result.nodes.length===1){
                    tagId=Utils.getGUID(TAG_PREFIX);
                }
                this.dirty = true;
                if (this.deviceSelected.type === DeviceType.WebAPI) {
                    // this.clearTags();
                }
                result.nodes.forEach((n: Node) => {
                    // 添加订阅时应以图形id作为主键
                    let tag = new Tag(tagId?tagId:Utils.getGUID(TAG_PREFIX));
                    tag.name = n.text;
                    tag.label = n.text;
                    tag.type = n.type;
                    if (this.deviceSelected.type === DeviceType.BACnet) {
                        tag.label = n.text;
                        tag.memaddress = n.parent?.id;
                    } else if (this.deviceSelected.type === DeviceType.WebAPI) {
                        tag.label = n.text;
                        if (n.class === NodeType.Reference) {
                            tag.memaddress = n.property;        // in memaddress save the address of the value
                            tag.options = n.todefine;           // save the id and value in text to set by select list
                            tag.type = n.type;
                        }
                    }
                    tag.address = n.id;
                    console.log(tag,result.device);
                    this.checkToAdd(tag, result.device);
                });
                console.log(this.deviceSelected);
                this.projectService.setDeviceTags(this.deviceSelected);
                console.log(this.tagsMap);
                if(result.nodes.length>1){
                    alert('您本次订阅多个属性，无法为您自动绑定主题！请点击“选择订阅按钮”绑定主题');
                }else{
                    this.variableId = tagId;
                    this.data.devices=Object.values(this.projectService.getDevices());
                    this.deviceList=this.data.devices;
                    this.onChanged();
                }
            }

        });
    }

    checkToAdd(tag: Tag, device: Device, overwrite: boolean = false) {
        let exist = false;
        Object.keys(device.tags).forEach((key) => {
            console.log(device.tags[key]);
            if (device.tags[key].id) {
                if (device.tags[key].id === tag.id) {
                    exist = true;
                }
            } else if (device.tags[key].name === tag.name) {
                console.log('111');
                exist = true;
            }
        });
        // console.log(device.tags,tag,exist);
        if (!exist || overwrite) {
            // 说明已经订阅过，需要用之前的tagid,仅保留一个
            device.tags[tag.id] = tag;
        }

        this.tagsMap[tag.id] = tag;
        this.deviceSelected.tags=this.tagsMap;
        console.log(tag,this.deviceSelected.tags);
        this.bindToTable(this.deviceSelected.tags);
    }

    private bindToTable(tags) {
        console.log(tags);
        if (!tags) {
            tags = {};
        }
        let arr=[];
        Object.values(tags).forEach((item: any)=>{
            arr.push({...item,value:typeof(item.value)==='object'?JSON.stringify(item.value):item.value});
        });
        console.log(',,,,,,,,',Object.keys(tags));
        this.hmiService.tagsSubscribe(Object.keys(tags));
    }
}
